package cate.game.play.proce.action.ctx;


import cate.common.table.d.GDPlay;
import cate.common.util.XT;
import cate.game.play.fighter.Fighter;
import cate.game.play.proce.action.po.SkillActionPO;
import cate.game.play.proce.move.MoveCtx;
import cate.game.play.proce.result.AimResult;
import cate.game.play.proce.stat.ActionStat;
import cate.game.play.proce.turn.TurnCtx;
import cate.game.play.skill.Skill;
import cate.game.play.skill.effect.SkillEffect;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

@NoteClass("Fighter技能释放ctx")
@Getter
public class SkillActionCtx extends ActionCtx<SkillActionPO>{

    @NoteField(value = "父Action",detail = "用于描述主子技能的层级关系")
    public SkillActionCtx parent;

    @NoteField("行动ctx")
    private MoveCtx move;

    @NoteField("技能")
    private Skill skill;

    @NoteField(value = "本次结算的目标",detail = "")
    private List<Fighter> targets;


    public SkillActionCtx(MoveCtx move, byte type, int actorPid, Skill skill, List<Fighter> targets) {
        this.round = move.getRound();
        this.po = new SkillActionPO();
        this.po.actorPid = actorPid;
        //临时忽略混乱的情况
        if (type == GDPlay.ActionType.SKILL_ACTIVE && skill.owner.buff.isChaos()) {
            this.po.type = GDPlay.ActionType.SKILL_CHAOS;
        } else {
            this.po.type = type;
        }
        if (skill != null) {
            po.tid = skill.tid;
        }
        this.stat = new ActionStat(move.stat);

        this.move = move;
        this.skill = skill;
        this.targets = targets;
    }

    /**
     * 释放一次技能 [][ 现在是实际效果 ][]
     *
     */
    public void settle() {
        Fighter actor = getActor();
        if (!XT.isBlank(targets)) {
            SkillEffect effect = new SkillEffect(skill);
            //目标选择后的脚本插件处理（当前技能）
            if (skill.active != null) {
                skill.active.afterSelectTargets(this, effect);
            }
            //目标选择后的被动处理(所有被动)
            actor.skill.forHandlers(a -> a.afterSelectTargets(this, effect));
            actor.buff.forHandlers(a -> a.afterSelectTargets(this, effect));
            for (Fighter tar : targets) {
                this.addResult(new AimResult().pidSet(tar.getPid()));
                //行动者出手前被动结算结算
                actor.skill.forHandlers(a -> a.beforeSkillSettleAsActor(this, effect, tar));
                actor.buff.forHandlers(a -> a.beforeSkillSettleAsActor(this, effect, tar));

                tar.skill.forHandlers(a -> a.beforeSkillSettleAsTarget(this, effect));
                tar.buff.forHandlers(a -> a.beforeSkillSettleAsTarget(this, effect));
                //技能效果结算
                effect.settle(this, tar);
                //行动者出手后被动结算结算
                tar.skill.forHandlers(a -> a.afterSkillSettleAsTarget(this, effect));
            }
        }
        //技能结算完毕后的主动处理（当前技能）
        if (skill.active != null) {
            skill.active.onSkillDone(this);
        }
        //技能结算完毕后的被动和buff处理
        actor.skill.forHandlers(a -> a.onSkillDone(this));
        //技能临时状态重制（清除之前临时指定的目标）
        this.skill.reset();
    }

    /** 追加子技能结算结果 */
    public void addChild(SkillActionCtx child){
        this.po.addChild(child.po);
    }

    @JsonIgnore
    public Fighter getActor() {
        return move.actor;
    }

    @JsonIgnore
    public TurnCtx getTurn(){return move.getTurn();}

    /**
     * 获取附加目标
     * @return
     */
    public List<Fighter> getExTargets() {
        List<Fighter> result = new ArrayList<>();
        for (int i = getSkill().cfg.getTargetNum(); i < getTargets().size(); i++) {
            result.add(getTargets().get(i));
        }
        return result;
    }
}
